package com.hyxt.DTO.protocols;

import com.hyxt.utils.bytes.BytesUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @Description: 部标808分情况处理类
 * @author shenp
 */
public class T808Case extends CommonCase implements ICase {
    private final static Log log = LogFactory.getLog(T808Case.class);
    /**
     * @Description:终端上来的数据判断是808协议
     * @param :data：源数据
     * @return
     * @throws Exception
     */
    @Override
    public boolean doCase(Object data) {
        byte[] bytes = (byte[]) data;
        // 第一位
        byte firstFlag = BytesUtil.getByte(0, bytes);
        // 最后一位
        byte lastFlag = BytesUtil.getByte(bytes.length - 1, bytes);
        // 正常源数据
        if (firstFlag == 0x7e && lastFlag == 0x7e) {

                return true;
        }
        return false;
    }

    @Override
    public byte getDataEnd() {
        return 0x7e;
    }

    @Override
    public byte getDataHead() {
        return 0x7e;
    }


    /**
     * @Description:转义还原
     *
     * @param data
     * @return
     * @throws IOException
     */
    @SuppressWarnings("resource")
    public static byte[] reverseEscapeData(byte[] data) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] reverseEscapedDatabytes;
        for (int i = 0; i < (data.length - 1); i++) {
            //判断消息尾
            if (data[i] == 0x7d && data[i + 1] == 0x02) {
                //转义
                bos.write((byte) 0x7e);
                i++;
            } else if (data[i] == 0x7d && data[i + 1] == 0x01) {
                //转义
                bos.write((byte) 0x7d);
                i++;
            } else if ((data[i] == 0x7d && data[i + 1] != 0x02) || (data[i] == 0x7d && data[i + 1] != 0x01)) {
                reverseEscapedDatabytes = null;
                try {
                    //关闭数据流
                    bos.close();
                } catch (IOException e) {
                    log.warn("", e);
                }
            } else {
                bos.write(data[i]);
            }
        }
        //如果数据倒数第二位不是数据位
        if (data[data.length - 2] != 0x7d) {
            if (data[data.length - 1] != 0x7d) {
                bos.write(data[data.length - 1]);
            } else {
                reverseEscapedDatabytes = null;
                try {
                    //关闭数据流
                    bos.close();
                } catch (IOException e) {
                    log.warn("", e);
                }
            }
        } else {
            // 倒数第二位等于125 则最后一位是转义位，不需要写入转以后的数据中
        }
        reverseEscapedDatabytes = bos.toByteArray();
        try {
            //关闭数据流
            bos.close();
        } catch (IOException e) {
            log.warn("", e);
        }
        return reverseEscapedDatabytes;
    }

    /**
     * @Description:此方法的作用是获取校验码
     * @param data 每一个data都表示一个8位的字节数组
     * @return
     */
    public static byte check(byte[] data) {
        //计算校验码
        byte checked = (byte) (data[1] ^ data[2]);
        for (int i = 3; i < (data.length - 2); i++) {
            checked = (byte) (checked ^ data[i]);
        }
        return checked;
    }
    /**
     * @Description:字节数组转化为字符串
     * @param :args
     * @return
     * @throws Exception
     */
    public static String bcdToStr(byte[] bytes) {

        StringBuffer temp = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            //移位操作
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
            temp.append((byte) (bytes[i] & 0x0f));
        }
        //返回计算结果
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString();
    }

    /**
     * @Description:获取唯一标识
     * @param data
     */
    @Override
    public String getSign(byte[] data){
        // 转义
        byte[] reverseBytes = null;
        // 转移还原
        reverseBytes = reverseEscapeData(data);
        //唯一标识
        String simNum = "";
        boolean check =check(reverseBytes) == BytesUtil.getByte(reverseBytes.length - 2, reverseBytes);
        if (check) {
            // 获取电话字节段
            byte[] simNumBytes = BytesUtil.cutBytes(5, 6, data);
            // 解析电话号码
            simNum = bcdToStr(simNumBytes);
        }
        return simNum;
    }

    public static void main(String[] args) {
        byte[] data = BytesUtil.toStringHex("7e0200002e01599940325200ce000000050000180301cb998e068251210322029e001e15042411362601040001e848020200640302029e04020004fc7e");
        T808Case t808Case = new T808Case();
        //String result = t808Case.doCase(data);
    }
}
